import $api from "@/static/js/api.js"

//editor参数为组件引用，相当于this
//dataList参数为公式字符的数组引用，每个字符都存储为一个对象。注意只能对数组内操作，改变数组地址无效
//item为点击的按钮对象
export default{
	/*
		系统功能
	*/
	//消除前一个字符
	"sysBack": function(editor, dataList, item){
		let x = editor.pointX;
		let y = editor.pointY;
		let idx;
		if(x>0){//删除前一个元素
			dataList[y].splice(x-1, 1);
			editor.pointX -=1;
		}else if(y>0){//删除换行
			idx = dataList[y-1].length;
			dataList[y-1].push(...dataList[y]);
			dataList.splice(y, 1);
			editor.pointX = idx;
			editor.pointY = y-1;
			editor.scrollToPoint();//滚动条移动到光标位置
		}
	},
	//消除后一个字符
	"sysDelete": function(editor, dataList, item){
		let x = editor.pointX;
		let y = editor.pointY;
		if(x<dataList[y].length){//删除后一个字符
			dataList[y].splice(x, 1);
		}else if(y<dataList.length-1){//删除换行
			dataList[y].push(...dataList[y+1]);
			dataList.splice(y+1, 1);
		}
	},
	//换行
	"sysReturn": function(editor, dataList, item){
		let x = editor.pointX;
		let y = editor.pointY;
		if(y<dataList[y].length){//光标后面有元素，截断
			let tempArr = dataList[y].splice(x);
			dataList.splice(y+1,0,tempArr);
		}else{//添加空行
			dataList.splice(y+1,0,[]);
		}
		editor.pointX =0;
		editor.pointY =y+1;
		editor.scrollToPoint();//滚动条移动到光标位置
	},
	//切换键盘
	"sysChangeKeyBoard": function(editor, dataList, item){
		if(item.value){
			editor.currKeyboard = item.value;
			editor.initKeyboard();
			editor.shiftAct =false;
		}
	},
	//shift键
	"sysShift": function(editor, dataList, item){
		editor.shiftAct = !editor.shiftAct;
		item.active = editor.shiftAct;
		editor.update();
	},
	//正常输入字符
	"sysInput": function(editor, dataList, item){
		let str = editor.shiftAct? item.shiftValue||item.value :item.value;
		//根据光标位置插入
		let x = editor.pointX,
			y = editor.pointY,
			len = str.length,
			strArr =[];
		//无字符则退出
		if(!str&&str!==0){
			return
		}
		//把内容拆分成字符对象
		for(let i=0; i<len; i++){
			let value = str.charAt(i);
			let res = {
				mode:"text",
				value
			}
			//如果是空白符则增加宽度
			if(value.trim()==""){
				res["value"] = " ";
				res["width"] = editor.spaceWidth;
			}
			if(item.color){
				res["color"] = item.color
			}
			if(item.bold){
				res["bold"] = item.bold
			}
			strArr.push(res)
		}
		dataList[y].splice(x, 0, ...strArr);
		editor.pointX += len;
		editor.scrollToPoint();//滚动条移动到光标位置
	},
	//插入数据对象，由附加组件提供
	"sysInsert": function(editor, dataList, data, point=0){
		let x = editor.pointX,
			y = editor.pointY,
			len =1;
		if(data.mode =="text"){//插入字符
			let str = data.value,
				strArr =[];
			len = str.length;
			//无字符则退出
			if(!str&&str!==0){
				return
			}
			//把内容拆分成字符对象
			for(let i=0; i<len; i++){
				let value = str.charAt(i);
				let res = Object.assign({}, data, {value});
				//如果是空白符则增加宽度
				if(value.trim()==""){
					res["value"] = " ";
					res["width"] = editor.spaceWidth;
				}
				strArr.push(res)
			}
			dataList[y].splice(x, 0, ...strArr);
		}else if(data.mode =="object"){//插入对象
			dataList[y].splice(x, 0, data);
		}
		editor.pointX += len +point;
		editor.scrollToPoint();//滚动条移动到光标位置
	},
	//光标控制，上
	"sysUp": function(editor, dataList, item){
		//光标上下移动无法校准，用样式查询校准代价极大。不管是根据字符数移动、设为行首、设为行尾都不是理想解决方案。目前方案为根据字符数移动
		let x = editor.pointX;
		let y = editor.pointY;
		if(y>0){
			editor.pointY -=1;
			let prevRowLen = dataList[y-1].length;
			if(prevRowLen <x){
				editor.pointX = prevRowLen;
			}
		}else{//第一行再执行则移动到行首
			editor.pointX =0;
		}
		editor.scrollToPoint();//滚动条移动到光标位置
	},
	//光标控制，下
	"sysDown": function(editor, dataList, item){
		//光标上下移动无法校准，用样式查询校准代价极大。不管是根据字符数移动、设为行首、设为行尾都不是理想解决方案。目前方案为根据字符数移动
		let x = editor.pointX;
		let y = editor.pointY;
		if(y< dataList.length-1){
			editor.pointY +=1;
			let nextRowLen = dataList[y+1].length;
			if(nextRowLen <x){
				editor.pointX = nextRowLen;
			}
		}else{//最后一行再执行则移动到行尾
			editor.pointX =dataList[y].length;
		}
		editor.scrollToPoint();//滚动条移动到光标位置
	},
	//光标控制，左
	"sysLeft": function(editor, dataList, item){
		let x = editor.pointX;
		let y = editor.pointY;
		if(x>0){
			editor.pointX -=1
		}else if(y>0){//行首移动到上一行行尾
			editor.pointY -=1;
			editor.pointX = dataList[y-1].length;
			editor.scrollToPoint();//滚动条移动到光标位置
		}
	},
	//光标控制，右
	"sysRight": function(editor, dataList, item){
		let x = editor.pointX;
		let y = editor.pointY;
		if(x< dataList[y].length){
			editor.pointX +=1
		}else if(y< dataList.length-1){//行尾移动到下一行行首
			editor.pointY +=1;
			editor.pointX =0;
			editor.scrollToPoint();//滚动条移动到光标位置
		}
	},
	//打开菜单（自定义附加组件）
	"sysOpenMenu": function(editor, dataList, item){
		let ref = editor.$refs[item.value];
		if(ref){
			ref.open()
		}
	},
	//打开或关闭输入框，使用原有输入方式
	"sysSwitchInput": function(editor, dataList){
		editor.inputMode = !editor.inputMode;
		editor.inputFocus = editor.inputMode;
	},
	
	
	/*
		自定义功能
	*/
	//公式解析，必须，不可改名。用于数据初始化
	//将公式字符串转换为组件用的数据格式，每个字符、控件都为一个对象，与键盘输入的最终数据格式相同。
	// [
	// 	{
	// 		mode:"text",	类型，text文字显示字符，object控件自定义显示值
	// 		value:"a",		数据值
	//		showValue:"",	显示值，type为object时有效
	// 		icon:"icon-xxx"	图标名，优先于值显示
	// 		color:""		自定义颜色
	// 		type:"primary"	主题色，使用icon、type为object时有效
	//		plain:false		镂空，使用icon、type为object时有效
	//		radius:""		圆角，使用icon、type为object时有效
	//		borderWidth:1	边框宽，使用icon、type为object时有效
	// 		bold:false		内容加粗，type为text时有效
	// 	}
	// ]
	"parseData": function(editor, dataList, string){
		dataList.splice(0,dataList.length);//清空行
		if(!string||typeof(string)!="string"){
			dataList.push([]);
			return
		}
		let rows = string.split("\n");
		for(let row of rows){
			let fields = row.match(/\$_widget_([^#]+)#/g);//得到的是按顺序出现的字段数组
			let tempArr =[];
			let str = row;
			//切分控件
			if(fields){
				//按顺序处理出现的字段，不管是否重复出现
				for(let field of fields){
					let idx = str.indexOf(field);
					let text = str.substring(0,idx);
					//切分字符
					for(let word of text){
						tempArr.push({
							mode: "text",
							value: word
						});
					}
					tempArr.push({
						mode:"object",
						value:field
					});
					str = str.substring(idx+field.length);
				}
			}
			if(str){
				//切分字符
				for(let word of str){
					tempArr.push({
						mode: "text",
						value: word
					});
				}
			}
			dataList.push(tempArr);
		}
		//设置变量的显示值
		let dataSet = editor.dataSet;
		let fieldOptions = (dataSet && dataSet.fieldOptions) ||[];
		for(let row of dataList){
			if(row&&row.length){
				for(let item of row){
					if(item.mode=="object"){
						let fieldObj = $api.arrFind(fieldOptions, {key:"value", value:item.value, format:"item"});
						if(fieldObj){
							Object.assign(item,{
								showValue: fieldObj.name,
								type: fieldObj.type ||"",
								color: fieldObj.color ||"",
								plain: fieldObj.hasOwnProperty("plain")?fieldObj.plain :true,
								radius: fieldObj.radius ||"0.25em",
								borderWidth: 1,
							})
						}
					}
				}
			}
		}
		//没有行时增加一个空行
		if(!dataList.length){
			dataList.push([])
		}
		//光标移动到末尾
		editor.pointY = dataList.length -1;
		editor.pointX = dataList[dataList.length-1].length;
	},
	//数据格式化，必须，不可改名。将组件数据还原为公式串
	"formatData": function(editor, dataList){
		let res ="";
		//清除空行
		for(let len=dataList.length,i=len-1; i>=0; i--){
			if(!dataList[i].length){
				dataList.splice(i, 1);
			}
		}
		for(let i=0,len1=dataList.length; i<len1; i++){
			let row = dataList[i];
			for(let j=0,len2=row.length; j<len2; j++){
				res += row[j].value
			}
			if(i<dataList.length-1){
				res += "\n"
			}
		}
		return res
	},
	
	//复制公式到缓存
	"copy": function(editor, dataList){
		let formula = editor.inValue;
		editor.$store.dispatch("user/setTemp", {
			data: {
				formulaClipboard: formula
			},
			success:()=>{
				$api.msg(editor.textSetting.tipCopySuccess)
			}
		})
	},
	//粘贴缓存公式
	"paste": function(editor, dataList){
		let formula = $api.objPathGet(editor.caches,"user.temporary.formulaClipboard");
		if(!formula){
			$api.msg(editor.textSetting.tipNoClipboard)
		}else{
			editor.inValue = formula;
			//重新初始化数据
			editor.initData();
			$api.msg(editor.textSetting.tipPasteSuccess)
		}
	},
	//重置公式
	"reset": function(editor, dataList){
		editor.inValue = editor.value;
		//重新初始化数据
		editor.initData();
		$api.msg(editor.textSetting.tipResetSuccess)
	},
}